﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Telerik.Sitefinity;
using Telerik.Sitefinity.Model;
using Telerik.Sitefinity.Events.Model;
using Telerik.Sitefinity.Modules.Events;
using Telerik.Sitefinity.GenericContent.Model;
using Telerik.Sitefinity.Workflow;
using System.Globalization;

namespace Migration.Classes
{
	public static class MigrationEvents
	{
		private static EventsManager m_EventsManager;

		static MigrationEvents()
		{
			m_EventsManager = EventsManager.GetManager(MigrationSettings.EventsProvider);
		}

		public static void CheckManagers()
		{
			if (m_EventsManager.Provider == null || MigrationSettings.ApplicationRestarted)
			{
				m_EventsManager = EventsManager.GetManager(MigrationSettings.EventsProvider);
			}
		}

		public static void ImportEvent(Telerik.Sitefinity.Services.Migration.MigrationEvent eventContent)
		{
			CheckManagers();

			var language = eventContent.Language;
            var culture = new CultureInfo(language);
			Guid id = eventContent.Id;
			string name = String.Empty;
			if (eventContent.MetaData["Title"] != null)
				name = eventContent.MetaData["Title"].ToString();

			// Check if the event already exists
			bool addNewLanguage = false;
			Event checkItem = m_EventsManager.GetEvents().Where(t => t.Id == id).FirstOrDefault();
			if (checkItem != null)
			{
				if (MigrationCultures.IsMultilingual)
				{
					if (checkItem.AvailableLanguages.Contains(language))
					{
						MigrationLogger.AppendLogMessage(MigrationUtils.GetLocalizableSkipMessage(name, eventContent.Language));
						return;
					}
					else
						addNewLanguage = true;
				}
				else
				{
					MigrationLogger.AppendLogMessage(MigrationUtils.GetLocalizableSkipMessage(name, String.Empty));
					return;
				}
			}

			Event eventItem;
			if (addNewLanguage)
				eventItem = checkItem;
			else
				eventItem = m_EventsManager.CreateEvent(id);

			string eventText = String.Empty;
			if (eventContent.Content != null)
			{
				eventText = eventContent.Content.ToString();
			}
			eventText = MigrationUrlRewriter.RewriteAlbumUrls(eventText);

			if (String.IsNullOrEmpty(language))
			{
				eventItem.Content = eventText;
				eventItem.UrlName = MigrationUtils.GetUrlName(eventContent.Url);
			}
			else
			{
				eventItem.SetString("Content", eventText, language);
				eventItem.UrlName[language] = MigrationUtils.GetUrlName(eventContent.Url);
			}

			DateTime publicationDate = DateTime.Now;

			foreach (KeyValuePair<string, object> metaData in eventContent.MetaData)
			{
				if (metaData.Value == null)
					continue;

				switch (metaData.Key)
				{
					case "Category":
                        MigrationTaxonomies.AddCategoryToOrganizer(metaData.Value.ToString(), eventItem.Organizer, culture);
						break;
					case "City":
						if (String.IsNullOrEmpty(language))
							eventItem.City = metaData.Value.ToString();
						else
							eventItem.City[language] = metaData.Value.ToString();
						break;
					case "Contact_Cell":
						if (String.IsNullOrEmpty(language))
							eventItem.ContactCell = metaData.Value.ToString();
						else
							eventItem.ContactCell[language] = metaData.Value.ToString();
						break;
					case "Contact_Email":
						eventItem.ContactEmail = metaData.Value.ToString();
						break;
					case "Contact_Name":
						if (String.IsNullOrEmpty(language))
							eventItem.ContactName = metaData.Value.ToString();
						else
							eventItem.ContactName[language] = metaData.Value.ToString();
						break;
					case "Contact_Phone":
						if (String.IsNullOrEmpty(language))
							eventItem.ContactPhone = metaData.Value.ToString();
						else
							eventItem.ContactPhone[language] = metaData.Value.ToString();
						break;
					case "Contact_Web":
						eventItem.ContactWeb = metaData.Value.ToString();
						break;
					case "Country":
						if (String.IsNullOrEmpty(language))
							eventItem.Country = metaData.Value.ToString();
						else
							eventItem.Country[language] = metaData.Value.ToString();
						break;
					case "Event_End":
						eventItem.EventEnd = DateTime.Parse(metaData.Value.ToString()); // Doubles with eventContent.Start
						break;
					case "Event_Start":
						eventItem.EventStart = DateTime.Parse(metaData.Value.ToString()); // Doubles with eventContent.End
						break;
					case "Expiration_Date":
						eventItem.ExpirationDate = DateTime.Parse(metaData.Value.ToString());
						break;
					case "Geomapping_Data":
						break;
					case "Publication_Date":
						publicationDate = DateTime.Parse(metaData.Value.ToString());
						break;
					case "State":
						if (String.IsNullOrEmpty(language))
							eventItem.State = metaData.Value.ToString();
						else
							eventItem.State[language] = metaData.Value.ToString();
						break;
					case "Street":
						if (String.IsNullOrEmpty(language))
							eventItem.Street = metaData.Value.ToString();
						else
							eventItem.Street[language] = metaData.Value.ToString();
						break;
					case "Title":
						if (String.IsNullOrEmpty(language))
							eventItem.Title = metaData.Value.ToString();
						else
							eventItem.Title[language] = metaData.Value.ToString();
						break;
					default:
					{
						string metaDataName = metaData.Key;
						var checkField = App.WorkWith().DynamicData().Type(typeof(Event)).Fields().Get().Where(f => f.FieldName == metaDataName).FirstOrDefault();
						if (checkField != null)
						{
							try
							{
								eventItem.SetValue(metaDataName.ToLowerInvariant(), metaData.Value.ToString());
							}
							catch (NullReferenceException) { };
						}
					}
					break;
				}
			}			

			eventItem.DateCreated = eventContent.DateCreated;
			eventItem.LastModified = eventContent.DateModified;
			eventItem.Owner = MigrationUsers.DefaultOwner;

			// Add the tags
            MigrationTaxonomies.AddTagsToOrganizer(eventContent.Tags, eventItem.Organizer, culture);

            // Add the URL name
			var urlName = String.Empty;

			if (String.IsNullOrEmpty(language))
				urlName = MigrationUtils.GetUrlName(eventItem.Title);
			else
				urlName = MigrationUtils.GetUrlName(eventItem.Title[language]);

            var checkUrl = m_EventsManager.GetEvents().Where(t => t.UrlName == urlName).FirstOrDefault();
            if (checkUrl != null)
                urlName = MigrationUtils.GetUrlName(eventItem.Id.ToString());

            if (String.IsNullOrEmpty(language))
                eventItem.UrlName = urlName;
            else
                eventItem.UrlName[language] = urlName;

			var masterId = eventItem.OriginalContentId;

			m_EventsManager.RecompileItemUrls<Event>(eventItem);

			if (eventItem.Status == ContentLifecycleStatus.Master)
			{
                System.Threading.Thread.CurrentThread.CurrentUICulture = culture;
				m_EventsManager.CheckOut(eventItem);
				masterId = eventItem.Id;
			}
			
			m_EventsManager.SaveChanges();

			var contextBag = new Dictionary<string, string>();
			contextBag.Add("ContentType", eventItem.GetType().FullName);

			WorkflowManager.MessageWorkflow(
				masterId,
				eventItem.GetType(),
				MigrationSettings.GenericContentProvider,
				"Publish",
				false,
				contextBag);

			// Add the comments
			MigrationComments.AddCommentsToEvent(eventItem.Id, eventContent.Comments, language);

			MigrationLogger.AppendLogMessage(MigrationUtils.GetLocalizableImportMessage(name, eventContent.Language));
		}
	}
}
